<template>
  <view class="appointment-page">
    <u--form
      labelPosition="left"
      :model="appointmentForm"
      :rules="rules"
      ref="appointmentForm"
    >
      <u-form-item
        label="申请人姓名"
        :required="true"
        labelWidth="90"
        prop="userName"
        class="u-form-item"
      >
        <u-input
          type="text"
          placeholder="请输入申请人姓名"
          border="bottom"
          v-model="appointmentForm.userName"
          clearable
        ></u-input>
      </u-form-item>
      <u-form-item
        label="身份证号码"
        :required="true"
        labelWidth="90"
        prop="userIdCard"
        class="u-form-item"
      >
        <u-input
          type="text"
          placeholder="请输入身份证号码"
          border="bottom"
          v-model="appointmentForm.userIdCard"
          clearable
        ></u-input>
      </u-form-item>

      <u-form-item
        label="联系方式"
        :required="true"
        labelWidth="90"
        prop="userPhone"
        class="u-form-item"
      >
        <u-input
          type="number"
          placeholder="请输入联系方式"
          border="bottom"
          v-model="appointmentForm.userPhone"
          clearable
        ></u-input>
      </u-form-item>

      <u-form-item
        label="验证码"
        labelWidth="90"
        prop="code"
        class="u-form-item"
      >
        <u-input
          type="text"
          placeholder="请填写验证码"
          border="bottom"
          v-model="appointmentForm.code"
        >
          <template slot="suffix">
            <u-button
              @tap="getCode"
              :text="tips"
              type="success"
              size="mini"
              :disabled="!canGetCode"
            />
          </template>
        </u-input>
      </u-form-item>

      <u-form-item
        label="单位"
        :required="true"
        labelWidth="90"
        prop="userCompany"
        class="u-form-item"
      >
        <u-input
          placeholder="请输入所在单位"
          border="bottom"
          v-model="appointmentForm.userCompany"
        ></u-input>
      </u-form-item>

      <u-form-item
        label="预约专家"
        :required="true"
        labelWidth="90"
        prop="professorName"
        class="u-form-item"
      >
        <u-input
          placeholder="请输入专家姓名"
          border="bottom"
          :suffixIcon="suffixIcon"
          v-model="appointmentForm.professorName"
          @input="handleProfessorInput"
          @change="handleProfessorId"
        ></u-input>
      </u-form-item>

      <u-form-item
        label="预约时间"
        :required="true"
        labelWidth="90"
        prop="appointmentTime"
        class="u-form-item"
      >
        <u-input
          placeholder="请选择时间"
          border="bottom"
          v-model="appointmentForm.appointmentTime"
          suffixIcon="arrow-right"
          suffixIconStyle="color: #909399"
          @focus="appointmentTimeFocus"
        ></u-input>
      </u-form-item>

      <u-form-item
        label="到访事项"
        :required="true"
        labelWidth="90"
        prop="appointmentContent"
        class="u-form-item"
      >
        <u-input
          type="text"
          placeholder="请输入到访事项"
          border="bottom"
          v-model="appointmentForm.appointmentContent"
          clearable
        ></u-input>
      </u-form-item>
    </u--form>

    <view class="buttons">
      <u-button
        class="submit-button"
        type="primary"
        shape="square"
        text="提交"
        @click="submit"
      />
      <u-button
        class="reset-button"
        type="error"
        shape="square"
        text="重置"
        @click="reset"
      />
    </view>

    <!-- 专家选择器 -->
    <u-picker
      :show="professorPickerShow"
      :columns="[professorColumns]"
      @confirm="professorPickerConfirm"
      @cancel="professorPickerClose"
      :closeOnClickOverlay="true"
    >
    </u-picker>

    <!-- 日期选择器 -->
    <u-datetime-picker
      :show="datePickerShow"
      v-model="datePickerTime"
      mode="datetime"
      :minDate="datePickerStart"
      :maxDate="datePickerEnd"
      @confirm="datePickerConfirm"
      @cancel="datePickerCancel"
    ></u-datetime-picker>
  </view>
</template>

<script>
  import { appointment, auth, professor } from "@/api";
  import { APPOINTMENT_FORM_RULES, ERROR_TYPE } from "@/common/constants";
  import { hideLoading, showLoading, showMessage } from "@/common/utils";
  import { ROUTE_PATHS } from "@/router/routes";
  import { debounce } from "lodash";

  export default {
    name: "appointment",
    data() {
      return {
        /**
         * 表单变量
         * @type {object}
         */
        appointmentForm: {
          /**
           * 申请人姓名
           * @type {string}
           */
          userName: "",
          /**
           * 身份证号码
           * @type {string}
           */
          userIdCard: "",
          /**
           * 联系方式(电话)
           * @type {number}
           */
          userPhone: "",
          /**
           * 验证码
           * @type {string}
           */
          code: "",
          /**
           * 用户单位
           * @type {string}
           */
          userCompany: "",
          /**
           * 预约专家姓名
           * @type {string}
           */
          professorName: "",
          /**
           * 预约时间
           * yyyy-mm-dd hh:MM:00
           * @type {string}
           */
          appointmentTime: "",
          /**
           * 到访事项
           * @type {string}
           */
          appointmentContent: "",
        },
        /**
         * 表单form规则
         * @type {object}
         */
        rules: APPOINTMENT_FORM_RULES,
        /**
         * 专家列表
         * @type {Array}
         * @property {string} name 专家姓名
         * @property {string} id 专家id
         */
        professorList: [],
        /**
         * 专家id
         * @type {string}
         */
        professorId: "",
        /**
         * 日期选择器时间戳
         * @type {number}
         */
        datePickerTime: "",
        /**
         * 日期选择器是否显现
         * @type {boolean}
         */
        datePickerShow: false,
        /**
         * 专家选择器是否显现
         * @type {boolean}
         */
        professorPickerShow: false,
        /**
         * 是否可以发送验证码
         * @type {boolean}
         */
        canGetCode: true,
        /**
         * 短信重发倒计时 单位：秒s
         * @type {number}
         */
        countdown: 30,
        /**
         * "获取验证码" 文本
         * @type {string}
         */
        tips: "获取验证码",
        /**
         * 判断专家是否是自动填入
         * @type {boolean}
         */
        isProfessorAutoInput: false,
      };
    },
    computed: {
      /**
       * 专家选择后缀图标
       */
      suffixIcon() {
        return this.professorId ? "checkmark-circle" : "minus-circle";
      },
      /**
       * 专家选择器列
       */
      professorColumns() {
        return this.professorList.map((item) => ({
          text: item.name + "-" + item.area,
          value: {
            id: item.id,
            name: item.name,
          },
        }));
      },
      /**
       * 日期选择器起始时间
       */
      datePickerStart() {
        // 当前时间往后一天
        return Number(new Date()) + 24 * 60 * 60 * 1000;
      },
      /**
       * 日期选择器结束时间
       */
      datePickerEnd() {
        // 当前时间往后30天
        return Number(new Date()) + 30 * 24 * 60 * 60 * 1000;
      },
    },
    /**
     * 页面传参
     */
    onShow() {
      this.fill();
    },
    /**
     *
     */
    created() {
      this.handleProfessorInput = debounce(() => {
        if (!this.isProfessorAutoInput) {
          this.professorInputConfirm();
        }
        this.isProfessorAutoInput = false;
      }, 500);
    },
    methods: {
      /**
       *
       * 提交表单 表单数据进行有效性检查
       * @param {object} data
       * @param {string} data.userName 预约人姓名
       * @param {string} data.userSfz 预约人身份证
       * @param {string} data.userCompany 预约人单位
       * @param {string} data.professorName 专家名称
       * @param {string} data.appointmentTime 到访时间
       * @param {string} data.appointmentContent 到访事项
       * @returns {void}
       */
      async submit() {
        try {
          let isValid = await this.$refs.appointmentForm.validate(); //validate() 表单自带方法：验证整个表单
          if (isValid) {
            showLoading("正在提交预约...");
            this.appointmentForm.professorId = this.professorId;
            const res = await appointment.addAppointment(this.appointmentForm);
            hideLoading();
            showMessage("预约提交至专家", true);
            setTimeout(() => {
              this.redirectToAppointmentList();
              this.$store.dispatch("appointment/setAppointmentId", res.data.id);
            }, 500);
          }
        } catch (error) {
          if (error.type === ERROR_TYPE.NETWORK) {
            return;
          }
          showMessage(error.msg || "请检查信息是否有误", false);
        } finally {
          hideLoading();
        }
      },
      /**
       * 专家id
       * @returns {void}
       */
      handleProfessorId() {
        if (!this.isProfessorAutoInput) {
          this.professorId = "";
        }
      },
      /**
       * 重置表单
       * @returns {void}
       */
      reset() {
        this.$refs.appointmentForm.resetFields();
        this.datePickerTime = ""; //时间选择器时间也重置
        this.fill();
      },

      /**
       * 联系方式(手机号)有效性检查 获取验证码
       * @returns {void}
       */
      async getCode() {
        try {
          await this.$refs.appointmentForm.validateField(
            "userTel",
            async (errorsRes) => {
              if (errorsRes.length == 0) {
                showLoading("验证码发送中...");
                const code = await this.sendCode(this.appointmentForm.userTel);
                this.appointmentForm.code = String(code);
                hideLoading();
                showMessage("验证码已发送", true);
                // 开始倒计时
                this.countTime();
              }
            }
          );
        } catch (error) {}
      },

      /**
       * 专家输入框-完成
       * @returns {void}
       */
      async professorInputConfirm() {
        try {
          await this.$refs.appointmentForm.validateField(
            "professorName",
            async (errorsRes) => {
              if (errorsRes.length === 0) {
                uni.hideKeyboard();
                await this.getProfessorList();
                if (this.professorList.length > 0) {
                  this.professorPickerShow = true;
                } else {
                  showMessage("未找到相关专家", false);
                }
              }
            }
          );
        } catch (error) {
        }
      },
      /**
       * 专家选择器点击遮罩关闭
       * @returns {void}
       */
      professorPickerClose() {
        this.professorPickerShow = false;
      },
      /**
       * 专家选择器-确定
       * @param {object} value
       * @param {Array} value.value
       * @param {object} value.value[0]
       * @param {object} value.value[0].value
       * @param {string} value.value[0].value.id 专家id
       * @param {string} value.value[0].value.name 专家姓名
       * @returns {void}
       */
      professorPickerConfirm(value) {
        const professor = value.value[0].value;
        this.selectProfessor(professor);
      },
      /**
       * 专家选择
       * @param {object} professor 专家信息
       * @param {string} professor.id 专家id
       * @param {string} professor.name 专家姓名
       * @returns {void}
       */
      selectProfessor(professor) {
        this.isProfessorAutoInput = true;
        this.appointmentForm.professorName = professor.name;
        this.professorId = professor.id;
        this.professorPickerShow = false;
      },
      /**
       * 日期选择框被点击聚焦
       * @returns {void}
       */
      appointmentTimeFocus() {
        if (!this.datePickerTime) {
          this.datePickerTime = this.datePickerStart;
        }
        this.datePickerShow = true;
        uni.hideKeyboard(); //隐藏键盘
      },

      /**
       * 日期选择器-确定
       * @param {object} confirmTime
       * @returns {void}
       */
      datePickerConfirm(confirmTime) {
        this.datePickerTime = confirmTime.value;
        this.datePickerShow = false;
        this.appointmentForm.appointmentTime = uni.$u.timeFormat(
          this.datePickerTime,
          "yyyy-mm-dd hh:MM:00"
        ); //格式化
      },

      /**
       * 日期选择器-取消
       * @returns {void}
       */
      datePickerCancel() {
        this.datePickerShow = false;
        this.datePickerTime = "";
      },

      /**
       * 获取专家列表
       */
      async getProfessorList() {
        showLoading("正在获取专家列表...");
        try {
          const res = await professor.getSimpleProfessorNameList({
            name: this.appointmentForm.professorName,
          });
          this.professorList = res.data;
        } catch (error) {
          if (error.type === ERROR_TYPE.NETWORK) {
            return;
          }
          showMessage(error.msg || "获取专家列表失败", false);
        } finally {
          hideLoading();
        }
      },

      /**
       * 获取用户信息
       * @param {String} name
       * @returns {void}
       */
      async fill() {
        if (this.$route.query.professor && this.$route.query.id) {
          this.selectProfessor({
            name: this.$route.query.professor,
            id: this.$route.query.id,
          });
          const userInfo = this.$store.state.user.userInfo ?? {};
          this.appointmentForm.userName = userInfo.name || "";
          this.appointmentForm.userPhone = userInfo.phone || "";
        }
      },

      /**
       * 发送验证码
       * @returns {string}
       */
      async sendCode() {
        showLoading("验证码发送中...");
        try {
          const res = await auth.getSmsCode({
            phone: this.appointmentForm.userPhone,
          });
          return res.data.code;
        } catch (error) {
          if (error.type === ERROR_TYPE.NETWORK) {
            return;
          }
          showMessage(error.msg || "获取验证码失败", false);
        } finally {
          hideLoading();
        }
      },

      /**
       * 倒计时方法
       * @returns {void}
       */
      countTime() {
        this.canGetCode = false;

        const tick = () => {
          if (this.countdown > 0) {
            this.countdown--;
            this.tips = `${this.countdown}s后重新获取`;
            setTimeout(tick, 1000);
          } else {
            this.canGetCode = true;
            this.tips = "获取验证码";
          }
        };
        setTimeout(tick, 1000);
      },

      /**
       * 跳转至预约列表
       * @returns {void}
       */
      redirectToAppointmentList() {
        uni.reLaunch({
          url: ROUTE_PATHS.APPOINTMENT_LIST,
        });
      },
    },
  };
</script>

<style lang="scss" scoped>
  .appointment-page {
    padding: 0 var(--margin-base);

    .u-form-item {
      padding: 0 var(--margin-small);
    }

    .professor-picker {
      padding: var(--margin-small);

      .professor-picker-item {
        padding: var(--margin-small);
        border-bottom: 1px solid var(--border-color);
      }
    }

    .buttons {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;

      padding: var(--margin-small) 0;
      gap: var(--margin-small);

      .submit-button {
        width: 600rpx;
      }

      .reset-button {
        width: 600rpx;
      }
    }
  }
</style>
